<template>
  <div
    class="container-body article-detail-body"
    :style="{ width: proxy.globalInfo.bodyWidth + 'px' }"
    v-if="Object.keys(articleInfo).length > 0"
  >
    <!-- 板块导航 -->
    <div class="board-info">
      <router-link :to="`/forum/${articleInfo.pBoardId}`" class="a-link">{{
        articleInfo.pBoardName
      }}</router-link>
      <span class="iconfont icon-right"></span>
      <template v-if="articleInfo.boardId">
        <router-link
          :to="`/forum/${articleInfo.pBoardId}${articleInfo.boardId}`"
          class="a-link"
          >{{ articleInfo.boardName }}</router-link
        >
        <span class="iconfont icon-right"></span>
      </template>
      <!-- 标题 -->
      <span>{{ articleInfo.title }}</span>
    </div>
    <!-- 文章详情 -->
    <div
      class="detail-container"
      :style="{ width: proxy.globalInfo.bodyWidth - 300 + 'px' }"
    >
      <!-- 文章 -->
      <div class="article-detail">
        <!-- 标题 -->
        <div class="title">
          {{ articleInfo.title }}
          <el-tag v-if="articleInfo.status == 0" type="danger">待审核</el-tag>
        </div>

        <!-- 用户信息 -->
        <div class="user-info">
          <Avatar :userId="articleInfo.userId" width="50"></Avatar>
          <div class="user-info-detail">
            <router-link
              class="nick-name a-link"
              :to="`/user/${articleInfo.userId}`"
              >{{ articleInfo.nickName }}</router-link
            >
            <div class="time-info">
              <span>{{ articleInfo.postTime }}</span>
              <span class="address"
                >&nbsp;&nbsp;·&nbsp;&nbsp;{{ articleInfo.userIpAddress }}</span
              >
              <span class="iconfont icon-eye-solid">
                {{
                  articleInfo.readCount === 0 ? "阅读" : articleInfo.readCount
                }}
              </span>
              <router-link
                :to="`/editPost/${articleInfo.articleId}`"
                class="a-link btn-edit"
                ><span
                  class="iconfont icon-edit"
                  v-if="articleInfo.userId == currentUserInfo.userId"
                  >编辑</span
                ></router-link
              >
            </div>
          </div>
        </div>
        <!-- 文章内容 -->
        <div
          class="detail github-markdown-body"
          id="detail"
          v-html="articleInfo.content"
        ></div>
      </div>
      <!-- 附件 -->
      <div class="attachment-panel" v-if="attachment" id="view-attachment">
        <div class="title">附件</div>
        <div class="attachment-info">
          <div class="iconfont icon-zip"></div>
          <div class="file-name">{{ attachment.fileName }}</div>
          <div class="size">
            {{ proxy.Utils.sizeToStr(attachment.fileSize) }}
          </div>
          <div>
            需要 <span class="integral">{{ attachment.integral }}</span> 积分
          </div>
          <div class="download-count">
            已下载{{ attachment.downloadCount }}次
          </div>
          <div class="download-btn">
            <el-button
              type="primary"
              size="small"
              @click="downLoadAttachment(attachment.fileId)"
              >下载</el-button
            >
          </div>
        </div>
      </div>
      <!-- 评论 -->
      <div class="comment-panel" id="view-comment">
        <CommentList
          :articleId="articleInfo.articleId"
          :articleUserId="articleInfo.userId"
          @updateCommentCount="updateCommentCount"
        ></CommentList>
      </div>
    </div>
    <!-- 目录 -->
    <div class="toc-panel">
      <div class="toc-container">
        <div class="toc-title">目录</div>
        <div class="toc-list">
          <template v-if="toArray.length == 0"
            ><div class="no-toc">未解析到目录</div></template
          >
          <template v-for="toc in toArray" v-else>
            <span
              @click="gotoAnchor(toc.id)"
              :class="['toc-item', toc.id == anchorId ? 'active' : '']"
              :style="{ paddingLeft: toc.level * 15 + 'px' }"
              >{{ toc.title }}</span
            >
          </template>
        </div>
      </div>
    </div>
  </div>
  <!-- 左侧快捷操作 -->
  <div class="quick-panel">
    <!-- 点赞 -->
    <el-badge
      :value="articleInfo.goodCount"
      type="info"
      :hidden="!articleInfo.goodCount > 0"
    >
      <div class="quick-item" @click="doLikeHandler">
        <span :class="['iconfont', 'icon-good', haveLike ? 'have-like' : '']">
        </span>
      </div>
    </el-badge>
    <!-- 评论 -->
    <el-badge
      :value="articleInfo.commentCount"
      type="info"
      :hidden="!articleInfo.commentCount > 0"
    >
      <div class="quick-item" @click="goToPostion('view-comment')">
        <span class="iconfont icon-comment"> </span>
      </div>
    </el-badge>
    <!-- 附件 -->
    <div class="quick-item" @click="goToPostion('view-attachment')">
      <span class="iconfont icon-attachment"> </span>
    </div>
    <!-- 图片预览 -->
    <ImageViewer
      ref="imageViewerRef"
      :imageList="previewImageList"
    ></ImageViewer>
  </div>
</template>

<script setup>
import hljs from "highlight.js";
import "highlight.js/styles/github-dark.css";
// import "highlight.js/styles/atom-one-light.css";
import CommentList from "@/views/forum/CommentList.vue";

import {
  ref,
  reactive,
  getCurrentInstance,
  onMounted,
  computed,
  watch,
  nextTick,
  onUnmounted,
} from "vue";
import { useRouter, useRoute } from "vue-router";
const { proxy } = getCurrentInstance();
import store from "@/store";
const router = useRouter();
const route = useRoute();
const api = {
  getArticleDetail: "/forum/getArticleDetail",
  doLike: "/forum/doLike",
  //因为是在新窗口打开 要加上api 没走拦截器
  attachmentDownload: "/api/forum/attachmentDownload",
  getUserDownloadInfo: "/forum/getUserDownloadInfo",
};
//获取当前用户信息
const currentUserInfo = ref({});
// 文章信息
const articleInfo = ref({});
// 附件
const attachment = ref({});
//是否点赞
const haveLike = ref(false);

const getArticleDetail = async (articleId) => {
  let result = await proxy.Request({
    url: api.getArticleDetail,
    params: {
      articleId: articleId,
    },
  });
  if (!result) return;
  articleInfo.value = result.data.forumArticle;
  attachment.value = result.data.attachment;
  haveLike.value = result.data.haveLike;
  //将当前一级板块信息存入store
  store.commit("setActivePBoardId", result.data.forumArticle.pBoardId);
  //将当前二级板块信息存入store
  store.commit("setActiveBoardId", result.data.forumArticle.boardId);
  // 图片预览
  imagePreview();
  //代码高亮
  heightLightCode();
  //获取目录
  markToc();
};
onMounted(() => {
  getArticleDetail(route.params.articleId);
});
//快捷操作
const quickPanelLeft = computed(() => {
  return `calc(50% - ${proxy.globalInfo.bodyWidth / 2}px - 100px)`;
});
const goToPostion = (domId) => {
  document.querySelector("#" + domId).scrollIntoView({ behavior: "smooth" });
};
//点赞
const doLikeHandler = async () => {
  if (!store.getters.getLoginUserInfo) {
    store.commit("showLogin", true);
    return;
  }
  let result = await proxy.Request({
    url: api.doLike,
    params: {
      articleId: articleInfo.value.articleId,
    },
  });
  if (!result) return;
  haveLike.value = !haveLike.value;
  let goodCount = 1;
  if (!haveLike.value) {
    goodCount = -1;
  }
  articleInfo.value.goodCount += goodCount;
};
//下载附件
// const currentUserInfo = ref({});
const downLoadAttachment = async (fileId) => {
  //判断是否登录
  if (!currentUserInfo.value) {
    store.commit("showLogin", true);
    return;
  }
  // if (!currentUserInfo.value) {
  //   store.commit("showLogin", true);
  //   return;
  // }
  //0积分
  // if (
  //   attachment.value.integral == 0 ||
  //   currentUserInfo.value.userId == articleInfo.value.userId
  // ) {
  //   downloadDo(fileId);
  //   return;
  // }
  //积分为0和当前用户id相同，直接下载
  if (
    attachment.value.integral == 0 ||
    currentUserInfo.value.userId == articleInfo.value.userId
  ) {
    downloadDo(fileId);
    return;
  }
  //获取用户下载信息
  let result = await proxy.Request({
    url: api.getUserDownloadInfo,
    params: {
      fileId: fileId,
    },
  });
  if (!result) {
    return;
  }
  // //判断用户是否下载
  if (result.data.haveDownload) {
    downLoadDo(fileId);
    return;
  }
  // //判断用户积分是否足够
  if (result.data.userIntegral || attachment.value.integral) {
    proxy.Message.warning("你的积分不足，无法下载");
    return;
  }

  proxy.Confirm(
    `你还有${result.data.userIntegral}积分，当前下载会扣除${attachment.value.integral}积分，确定要下载吗？`,
    () => {
      downLoadDo(fileId);
    }
  );
};
const downLoadDo = (fileId) => {
  //打开一个新窗口下载 返回的是文件流
  document.location.href = api.attachmentDownload + "?fileId=" + fileId;
  attachment.value.downloadCount += 1;
};
//监听登录用户
// watch(
//   () => store.state.loginUserInfo,
//   (newVal, oldVal) => {
//     currentUserInfo.value = newVal || {};
//   },
//   { immediate: true, deep: true }
// );
//文章图片预览
const previewImageList = ref([]);
const imageViewerRef = ref(null);
const imagePreview = () => {
  nextTick(() => {
    const imageNodeList = document
      .querySelector("#detail")
      .querySelectorAll("img");
    const imageList = [];
    imageNodeList.forEach((item, index) => {
      const src = item.getAttribute("src");
      imageList.push(src);
      item.addEventListener("click", () => {
        imageViewerRef.value.show(index);
      });
    });
    previewImageList.value = imageList;
  });
};
//代码高亮
const heightLightCode = () => {
  nextTick(() => {
    let blocks = document.querySelectorAll("pre code");
    blocks.forEach((item) => {
      hljs.highlightElement(item);
    });
  });
};
//更新评论数量
const updateCommentCount = (totalCount) => {
  articleInfo.value.commentCount = totalCount;
};
//获取目录
const toArray = ref([]);

const markToc = () => {
  nextTick(() => {
    const tocTags = ["H1", "H2", "H3", "H4", "H5", "H6"];
    const contentDom = document.querySelector("#detail");
    let childNodes = contentDom.childNodes;
    let index = 0;
    childNodes.forEach((item) => {
      let tagName = item.tagName;
      if (tagName == undefined || !tocTags.includes(tagName.toUpperCase())) {
        return true;
      }
      index++;
      let id = "toc+" + index;
      item.setAttribute("id", id);
      toArray.value.push({
        id: id,
        title: item.innerText,
        level: Number.parseInt(tagName.substring(1)),
        offsetTop: item.offsetTop,
      });
    });
  });
};
//跳到锚点位置
const anchorId = ref(null);
const gotoAnchor = (domId) => {
  // const dom = document.querySelector("#" + domId);错误方法
  const dom = document.getElementById(domId);
  dom.scrollIntoView({
    behavior: "smooth",
    block: "start",
  });
};
//监听滚动
const listenerScroll = () => {
  let currentScrollTop = getScrollTop();
  toArray.value.some((element, index) => {
    if (
      (index < toArray.value.length - 1 &&
        currentScrollTop >= toArray.value[index].offsetTop &&
        currentScrollTop < toArray.value[index + 1].offsetTop) ||
      (index == toArray.value.length - 1 &&
        currentScrollTop < toArray.value[index].offsetTop)
    ) {
      anchorId.value = element.id;
      return true;
    }
  });
};
//获取滚动条高度
const getScrollTop = () => {
  let scrollTop =
    document.documentElement.scrollTop ||
    window.pageYOffset ||
    document.body.scrollTop;
  return scrollTop;
};
//监听当前用户信息
watch(
  () => store.state.loginUserInfo,
  (newVal, oldVal) => {
    currentUserInfo.value = newVal;
  },
  { immediate: true, deep: true }
);
onMounted(() => {
  window.addEventListener("scroll", listenerScroll, false);
});
onUnmounted(() => {
  window.removeEventListener("scroll", listenerScroll, false);
});
</script>

<style lang="scss">
.article-detail-body {
  position: relative;
  .board-info {
    line-height: 40px;
    font-size: 14px;
    .icon-right {
      margin: 0px 10px;
    }
  }
  .detail-container {
    .article-detail {
      background: #fff;
      padding: 10px;

      .title {
        font-size: 16px;
        font-weight: bold;
      }
      .user-info {
        display: flex;
        align-items: center;
        margin-top: 15px;
        padding-bottom: 10px;
        border-bottom: 1px solid #ddd;
        .user-info-detail {
          margin-left: 10px;
          .nick-name {
            text-decoration: none;
            color: #4e5969;
            font-size: 15px;
          }
          .nick-name:hover {
            color: var(--link);
          }
          .time-info {
            font-size: 13px;
            color: var(--text2);
            // .address {
            // }
            .icon-eye-solid {
              color: #86909c;
              font-size: 14px;
              margin-left: 10px;
            }
            .icon-eye-solid:before {
              padding-right: 3px;
            }
            .btn-edit {
              .iconfont {
                font-size: 14px;
              }
            }
          }
        }
      }
      .detail {
        // display: flex;
        // flex-direction: column;
        // gap: 20px;
        // padding: 10px 15px;
        letter-spacing: 1px; //改文字间距
        line-height: 22px;
        a {
          text-decoration: none;
          color: var(--link);
        }
        img {
          max-width: 90%;
          cursor: pointer;
        }
      }
    }
    .attachment-panel {
      background: #fff;
      margin-top: 20px;
      padding: 20px;
      .title {
        font-size: 18px;
      }
      .attachment-info {
        display: flex;
        align-items: center;
        line-height: 1;
        gap: 10px;
        color: #9f9f9f;
        margin-top: 10px;
        .icon-zip {
          font-size: 20px;
          color: #6ca1f7;
        }
        .file-name {
          color: #6ca1f7;
        }
        .integral {
          color: red;
          padding: 0 5px;
        }
      }
    }
    .comment-panel {
      background: #fff;
      margin-top: 20px;
      padding: 20px;
    }
  }
  .toc-panel {
    position: absolute;
    top: 45px;
    right: 0;
    width: 285px;
    .toc-container {
      position: fixed;
      width: 285px;
      background-color: #fff;
      .toc-title {
        font-size: 16px;
        padding: 10px;
        border-bottom: 1px solid #ddd;
      }
      .toc-list {
        max-height: calc(100vh - 200px);
        overflow: auto;
        padding: 5px;
        .no-toc {
          text-align: center;
          color: #646262;
          line-height: 40px;
          font-size: 13px;
        }
        .toc-item {
          line-height: 35px;
          cursor: pointer;
          display: block;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
          color: #555666;
          border-radius: 3px;
          font-size: 14px;
          border-left: 2px solid #fff;
          height: 40px;
        }
        .toc-item:hover {
          background-color: #f1f1f1;
          border-radius: 0px 3px 3px 0px;
        }
        .active {
          background-color: #f1f1f1;
          border-left: 2px solid #6ca1f7;
          border-radius: 0px 3px 3px 0px;
        }
      }
    }
  }
}
.quick-panel {
  position: fixed;
  top: 200px;
  left: v-bind(quickPanelLeft); // 使用计算值
  width: 50px;
  display: flex;
  flex-direction: column;
  gap: 30px;
  .el-badge__content.is-fixed {
    top: 5px;
    right: 15px;
  }
  .quick-item {
    width: 50px;
    height: 50px;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 50%;
    background: #fff;
    color: var(--text2);
    cursor: pointer;
    .iconfont {
      font-size: 22px;
    }
    .have-like {
      color: red;
    }
  }
}
</style>
